package com.tdd.api.server.base.exception;

import com.tdd.api.server.base.returns.RespCode;
import com.tdd.api.server.base.returns.RespEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingRequestHeaderException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;

/**
 * @author lanchunqiu
 * @version V1.0.0
 * @description: 统一异常处理
 * @date 2019/9/3 15:50
 * @copyright Copyright © 2019 
 */
@Slf4j
@RestControllerAdvice
public class ExceptionHandlerAdvice {

    /**
     *
     * @param exception
     * @param request
     * @return
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler({MethodArgumentNotValidException.class, BindException.class})
    public RespEntity dealHibernateException(Exception exception, HttpServletRequest request) {
        log.error("exception={}", exception);
        BindingResult bindResult = null;
        if (exception instanceof BindException) {
            bindResult = ((BindException) exception).getBindingResult();
        } else if (exception instanceof MethodArgumentNotValidException) {
            bindResult = ((MethodArgumentNotValidException) exception).getBindingResult();
        }
        String msg;
        if (bindResult != null && bindResult.hasErrors()) {
            msg = bindResult.getAllErrors().get(0).getDefaultMessage();
            return new RespEntity(RespCode.PARAMETERS_ERROR, msg);
        }else {
            msg = "系统繁忙，请稍后重试...";
            return new RespEntity(RespCode.PARAMETERS_ERROR, msg);
        }
    }

    /**
     *
     * @param request
     * @param ex
     * @return
     */
    @ExceptionHandler(MissingRequestHeaderException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public RespEntity handleMissingRequestHeaderException(HttpServletRequest request, MissingRequestHeaderException ex) {
        log.error("ex={}", ex);
        String msg = "缺少必要的header信息";
        RespEntity result = new RespEntity(RespCode.SERVER_ERROR, msg);
        return result;
    }

    /**
     *
     * @param request
     * @param ex
     * @return
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public RespEntity handleExceptions(HttpServletRequest request, Exception ex) {
        log.error("ex={}", ex);
        RespEntity result = new RespEntity(RespCode.SERVER_ERROR,ex.getMessage());
        return result;
    }

    /**
     *
     * @param request
     * @param ex
     * @return
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ResponseBody
    public RespEntity handleRequestMethodExceptions(HttpServletRequest request, HttpRequestMethodNotSupportedException ex) {
        log.error("ex={}", ex);
        RespEntity result = new RespEntity(RespCode.REQUEST_METHOD_ERROR,ex.getMessage());
        return result;
    }

    /**
     *
     * @param request
     * @param ex
     * @return
     */
    @ExceptionHandler( NoHandlerFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ResponseBody
    public RespEntity handleRequestMethodExceptions(HttpServletRequest request, NoHandlerFoundException ex) {
        log.error("ex={}", ex);
        RespEntity result = new RespEntity(RespCode.REQUEST_PATH_NOT_FOUND,ex.getMessage());
        return result;
    }

    /**
     *
     * @param request
     * @param ex
     * @return
     */
    @ExceptionHandler(BusinessException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public RespEntity handleBusinessExceptions(HttpServletRequest request, BusinessException ex) {
        log.error("ex={}", ex);
        RespEntity result = new RespEntity(ex.getRespCode(), ex.getMsg());
        return result;
    }


}
